#pragma once
#include <string>

// find namespace of class
template<typename T>
constexpr std::string_view get_type_name() {
#ifdef __GNUC__
    std::string_view name = __PRETTY_FUNCTION__;
    auto start = name.find("T = ") + 4;
    auto end = name.find_last_of(']');
    return name.substr(start, end - start);
#elif defined(_MSC_VER)
    std::string_view name = __FUNCSIG__;
    auto start = name.find("get_type_name<") + 14;
    auto end = name.find_last_of('>');
    return name.substr(start, end - start);
#else
    return "unknown";
#endif
}

template<typename T>
constexpr bool is_in_namespace(const std::string_view& ns_name) {
    auto type_name = get_type_name<T>();
    return type_name.find(ns_name) != std::string_view::npos;
}

template<typename T>
constexpr bool is_fb_type() {
    return is_in_namespace<T>("::flatbuffers::");
}

template<typename T>
constexpr bool is_pb_type() {
    return is_in_namespace<T>("::google::protobuf::");
}
